# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_python//python:proto.bzl", "py_proto_library")
load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library")
load("//pw_build:compatibility.bzl", "host_backend_alias", "incompatible_with_mcu")
load("//pw_build:pw_facade.bzl", "pw_facade")
load("//pw_build:python.bzl", "pw_py_binary")
load("//pw_protobuf_compiler:pw_proto_library.bzl", "pwpb_proto_library")
load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test")

package(default_visibility = ["//visibility:public"])

licenses(["notice"])

cc_library(
    name = "epoch",
    hdrs = [
        "public/pw_chrono/epoch.h",
    ],
    strip_include_prefix = "public",
)

cc_library(
    name = "virtual_clock",
    hdrs = [
        "public/pw_chrono/virtual_clock.h",
    ],
    strip_include_prefix = "public",
)

pw_facade(
    name = "system_clock",
    srcs = [
        "system_clock.cc",
    ],
    hdrs = [
        "public/pw_chrono/internal/system_clock_macros.h",
        "public/pw_chrono/system_clock.h",
    ],
    backend = ":system_clock_backend",
    strip_include_prefix = "public",
    tags = ["noclangtidy"],
    deps = [
        ":epoch",
        ":virtual_clock",
        "//pw_preprocessor",
    ],
)

label_flag(
    name = "system_clock_backend",
    build_setting_default = ":system_clock_unspecified_backend",
)

host_backend_alias(
    name = "system_clock_unspecified_backend",
    backend = "//pw_chrono_stl:system_clock",
)

pw_facade(
    name = "system_timer",
    hdrs = [
        "public/pw_chrono/system_timer.h",
    ],
    backend = ":system_timer_backend",
    strip_include_prefix = "public",
    tags = ["noclangtidy"],
    deps = [
        ":system_clock",
    ],
)

label_flag(
    name = "system_timer_backend",
    build_setting_default = ":system_timer_unspecified_backend",
)

host_backend_alias(
    name = "system_timer_unspecified_backend",
    backend = "//pw_chrono_stl:system_timer",
)

proto_library(
    name = "chrono_proto",
    srcs = [
        "chrono.proto",
    ],
    import_prefix = "pw_chrono_protos",
    strip_import_prefix = "/pw_chrono",
    deps = [
        "//pw_tokenizer:tokenizer_proto",
    ],
)

py_proto_library(
    name = "chrono_proto_pb2",
    deps = [":chrono_proto"],
)

pwpb_proto_library(
    name = "chrono_proto_pwpb",
    deps = [":chrono_proto"],
)

cc_library(
    name = "simulated_system_clock",
    hdrs = [
        "public/pw_chrono/simulated_system_clock.h",
    ],
    strip_include_prefix = "public",
    deps = [
        ":system_clock",
        "//pw_sync:interrupt_spin_lock",
    ],
)

pw_cc_test(
    name = "simulated_system_clock_test",
    srcs = [
        "simulated_system_clock_test.cc",
    ],
    deps = [":simulated_system_clock"],
)

pw_cc_test(
    name = "system_clock_facade_test",
    srcs = [
        "system_clock_facade_test.cc",
        "system_clock_facade_test_c.c",
    ],
    deps = [
        ":system_clock",
        "//pw_preprocessor",
    ],
)

pw_cc_test(
    name = "system_timer_facade_test",
    srcs = [
        "system_timer_facade_test.cc",
    ],
    deps = [
        ":system_clock",
        ":system_timer",
        "//pw_sync:thread_notification",
    ],
)

pw_py_binary(
    name = "generate_build_time_header",
    srcs = ["generate_build_time_header.py"],
)

genrule(
    name = "build_time_header",
    outs = ["build_time.h"],
    cmd = "$(execpath :generate_build_time_header) --bazel $@",
    stamp = True,
    tools = [":generate_build_time_header"],
)

cc_library(
    name = "wrap_time_build_time",
    srcs = [
        "wrap_time_build_time.cc",
        ":build_time_header",
    ],
)

cc_library(
    name = "wrap_time_system_clock",
    srcs = ["wrap_time_system_clock.cc"],
    # Fails on MacOS only.
    features = ["-conversion_warnings"],
    linkopts = [
        "-Wl,--wrap=gettimeofday",
        "-Wl,--wrap=time",
    ],
    deps = [":system_clock"],
    alwayslink = 1,
)

filegroup(
    name = "doxygen",
    srcs = [
        "public/pw_chrono/simulated_system_clock.h",
        "public/pw_chrono/system_clock.h",
        "public/pw_chrono/system_timer.h",
        "public/pw_chrono/virtual_clock.h",
    ],
)

sphinx_docs_library(
    name = "docs",
    srcs = [
        "backends.rst",
        "docs.rst",
    ],
    prefix = "pw_chrono/",
    target_compatible_with = incompatible_with_mcu(),
)
